﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Common.Utilities;
using ZedGraph;

namespace WindowsUserControl.UIUpdateWrapper
{
    /// <summary>
    /// 
    /// </summary>
    public class OverlayedColumnBarZedChartUpdator
    {
        private ZedGraphControl _ZedGraph;
        private Dictionary<string, List<double>> _Values;
        private List<string> _StackLabels;
        private string _Title;
        private string _XLabel;
        private string _YLabel;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="zgc"></param>
        /// <param name="values"></param>
        /// <param name="stackLabels"></param>
        /// <param name="title"></param>
        /// <param name="xLabel"></param>
        /// <param name="yLabel"></param>
        public OverlayedColumnBarZedChartUpdator(ZedGraphControl zgc, 
            Dictionary<string,List<double>> values,
            List<string> stackLabels,
            string title, string xLabel, string yLabel)
        {
            this._ZedGraph = zgc;
            this._Values = values;
            this._Title = title;
            this._XLabel = xLabel;
            this._YLabel = yLabel;
            this._StackLabels = stackLabels;

            this._ZedGraph.Invoke(new MethodInvoker(this.UpdateChart));
        }

        private void UpdateChart()
        {
            this._ZedGraph.GraphPane.CurveList.Clear();
            this._ZedGraph.GraphPane.GraphObjList.Clear();

            GraphPane myPane = this._ZedGraph.GraphPane;

            // Set the Titles
            myPane.Title.Text = this._Title;
            myPane.XAxis.Title.Text = this._XLabel;
            myPane.YAxis.Title.Text = this._YLabel;

            // populate data arrays
            int columnCount = this._Values.Count;
            string[] xLabels = new string[columnCount];
            this._Values.Keys.CopyTo(xLabels, 0);
            int stackCount = this._Values[xLabels[0]].Count;
            double[,] dataArray = new double[stackCount,columnCount];
            for(int stack=0;stack <stackCount;stack ++)
            {
                for(int column =0;column<columnCount;column++)
                {
                    string label = xLabels[column];
                    List<double> values = this._Values[label];
                    dataArray[stack, column] = values[stack];
                }
            }
            int stack1 = 0;
            while(stack1<stackCount-1)
            {
                for(int i=0;i<columnCount;i++)
                {
                    dataArray[stack1 + 1, i] += dataArray[stack1, i];
                }
                stack1++;
            }

            // add legend 
            List<Color> randomColors = ColorUtil.GetDistinctRandomColors(stackCount);
            for (int i = 0; i < this._StackLabels.Count; i++)
            {
                double[] measurements = new double[columnCount];
                for(int k=0;k<columnCount;k++)
                {
                    measurements[k] = dataArray[i, k];
                }
                myPane.AddBar(_StackLabels[i], null, measurements, randomColors[i]);
                
            }

            // add label & bar
            const float shift = 5;
            for(int i=0;i<columnCount;i++)
            {
                string xLabel = xLabels[i];
                List<double> pairedVals = this._Values[xLabel];
                double sum = 0;
                foreach (double val in pairedVals)
                {
                    sum += val;
                }
                TextObj txtObj = new TextObj(xLabel, (float)(i + 1), (float)(sum+shift));
                txtObj.Location.CoordinateFrame = CoordType.AxisXYScale;
                txtObj.Location.AlignH = AlignH.Left;
                txtObj.Location.AlignV = AlignV.Center;
                txtObj.FontSpec.Border.IsVisible = false;
                txtObj.FontSpec.Fill.IsVisible = false;
                txtObj.FontSpec.Angle = 90;
                myPane.GraphObjList.Add(txtObj);
            }


            // style
            myPane.BarSettings.Type = BarType.Overlay;
            myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);

            // update scale
            this._ZedGraph.AxisChange();

            // leave room for label
            myPane.YAxis.Scale.Max += myPane.YAxis.Scale.MajorStep;
        }
    }
}
